home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 076-100 / disk_087 / warptext / warptext.asm < prev    next >
Assembly Source File  |  1992-05-06  |  18KB  |  427 lines

  1. * --------------------------------------------------------------------------
  2. * WarpText.asm -- (PRE-RELEASE!) an ultra-fast,                   Bill Kelly
  3. * super_spiffy text-emitting routine.  :-)                        06/04/87
  4. *
  5. * Copyright 1987 by Bill W. Kelly.
  6. *
  7. * THANKS:
  8. *
  9. *   Many thanks to Hayes C. Haugen for giving me the idea to write
  10. *   these routines-- I took one look at Blitz and thought:
  11. *   "I've *gotta* DO that!"  Well, thanks, Hayes -- I've done it.
  12. *   Now, if I could *only* make a file requestor as nice as yours!!! :-)
  13. *
  14. *   Thanks also to the people who gave me suggestions about ways to improve
  15. *   the WarpText routines I had originally written!  These are much nicer...
  16. *
  17. * COPYRIGHT NOTICE:
  18. *
  19. *   This code, and the name "WarpText," is Copyright 1987 by Bill W. Kelly.
  20. *
  21. * DISTRIBUTION INFORMATION:
  22. *
  23. *   You may distribute this code in any way you want to.  I would prefer
  24. *   that you charge less than $10 for distribution, however, and please
  25. *   leave this whole notice intact.  Please also distribute the file
  26. *   "WarpText.i" together with "WarpText.asm" (this file).  Thanks!
  27. *
  28. *   NOTE: IF YOU ARE GOING TO MODIFY THE CODE, please make a little note
  29. *         containing the date, what the original code was, and anything
  30. *         else you deem necessary...
  31. *
  32. * USING WARPTEXT IN A PROGRAM:
  33. *
  34. *   That's what it's here for!
  35. *
  36. *   If you are going to distribute the source code with your program
  37. *   please follow the restrictions under "DISTRIBUTION INFORMATION."
  38. *
  39. *   It would be neat, especially if you aren't distributing the source
  40. *   with your program, if you could find a place somewhere in your program
  41. *   (the "ABOUT" menu, for instance) to say something like,
  42. *   "Using Bill Kelly's WarpText routines for speed!," however if you
  43. *   don't seem to be able to do this... don't worry about it.  I would
  44. *   really appreciate it, though!  Thanks!
  45. *
  46. *   PLEASE CONTACT ME BEFORE USING THIS CODE IN A COMMERCIAL PROGRAM!
  47. *
  48. * MY ADDRESS:
  49. *
  50. *   NAME: Bill W. Kelly
  51. *   UUCP: {akgua, hplabs!hp-sdd, sdcsvax}!crash!pnet01!billk
  52. *   ARPA: crash!pnet01!billk@nosc
  53. *   INET: billk@pnet01.CTS.COM    | For UUCP, don't do just pnet01!billk;
  54. *   USPS: 2507 Caminito La Paz    | please include the crash!pnet01!billk.
  55. *         La Jolla, CA  92037     | Thanks!
  56. *   FONE: (619) 454-1307
  57. *
  58. * PRE-RELEASE:
  59. *
  60. *   This is a pre-release version of WarpText.  In about half a month or
  61. *   a month I plan to release a version of WarpText that comes with
  62. *   an example program and has any reported bugs fixed.  I will also
  63. *   be adding a real clearscreen (clear 'window') on a formfeed and some
  64. *   other features.  If any of the code looks strange, or you notice
  65. *   that I'm doing something like "moveq #0,dn" where I don't need to...
  66. *   Well, you might mention it to save me time, although I will be going
  67. *   back over the code to look for little things like this...
  68. *   I took as much time as my schedule would permit to write this and get
  69. *   it debugged and out.  There are probably a few strange or unneeded
  70. *   things I've done -- I haven't *really* LOOKED at the code yet,
  71. *   though I have tested it...  Ah well...
  72. *
  73. * GEE, THAT'S ALL VERY NICE, BUT HOW DO I CALL THESE ROUTINES???
  74. *
  75. *   Well, I have given you yet another structure to deal with...
  76. *   Let me introduce you to WarpInfo...
  77. *
  78. *   STRUCTURE   WarpInfo,0      ; ...the <I> denotes internal use.
  79. *       APTR    wi_TextFont     ;     Pointer to a TextFont structure.
  80. *       APTR    wi_BitMap       ;     Pointer to a BitMap structure.
  81. *       WORD    wi_WhichPlane   ;     Which bitplane to render into.
  82. *       WORD    wi_Left         ;     Left edge of 'window' in char loc's.
  83. *       WORD    wi_Top          ;     Top edge of 'window' in char loc's.
  84. *       WORD    wi_Width        ;     Width of 'window' in char loc's.
  85. *       WORD    wi_Height       ;     Height of 'window' in char loc's.
  86. *       APTR    wi_WindowTop    ; <I> Address of top of 'window.'
  87. *       APTR    wi_CurLine      ; <I> Address of start of current line.
  88. *       APTR    wi_LastLine     ; <I> Address of start of last line.
  89. *       WORD    wi_CurX         ; <I> Current X position.
  90. *       WORD    wi_LastX        ; <I> Maximum X position on a line.
  91. *       WORD    wi_BPMod        ; <I> # total possible chars on a line in bp
  92. *       WORD    wi_Modulo       ; <I> Add this to get to next line.
  93. *       LABEL   wi_SIZE
  94. *
  95. *   When you assemble WarpText.asm, it will expect to find this structure
  96. *   in graphics directory of your include files.  It will do:
  97. *   INCLUDE "graphics/warptext.i"   I have already created a file called
  98. *   "WarpText.i" which should be distributed along with this file.
  99. *
  100. *   Now about the routines: there are only four routines that make up
  101. *   WarpText.  You must call the InitWarpInfo routine before calling any
  102. *   of the other three routines.
  103. *
  104. *   Please see each routine for information about how to call them.
  105. *
  106. * OH YEAH, BUG REPORTS:
  107. *
  108. *   What, bugs in *my* code???  (Shut up, Bill...!)
  109. *
  110. *   I would really appreciate hearing about the problems you find in
  111. *   my code!  I welcome your input.  'Ya know, suggestions, questions,
  112. *   comments, flames?, etc...
  113. *
  114. *   Remember, this is a pre-release version of WarpText.  I plan to release
  115. *   a version that *actually* has an EXAMPLE program with it. (Gee...)
  116. *   In this version I will fix all the reported bugs and may make some
  117. *   changes if anyone comes up with any interesting suggestions.
  118. *
  119. *   Anyway,
  120. *
  121. * HAVE FUN!                                                         Bill
  122. * --------------------------------------------------------------------------
  123.  
  124.     XDEF InitWarpInfo
  125.     XDEF GotoXY
  126.     XDEF GetXY
  127.     XDEF WarpText
  128.  
  129.             NOLIST  ; I don't want to see all of this junque...
  130.  
  131.                INCLUDE "graphics/text.i"
  132.                INCLUDE "graphics/gfx.i"
  133.                INCLUDE "graphics/warptext.i"
  134.  
  135.             LIST    ; Turn listing back on...
  136.  
  137. * -----------------------------------------
  138. * Seems like a good place to put some code:
  139. * -----------------------------------------
  140.  
  141.             CODE    ; Ready...FIRE! ...Aim?
  142.  
  143. * --------------------------------------------------------------------------
  144. * INITWARPINFO NEEDS:
  145. *
  146. * a0 - Pointer to an instance of the WarpInfo structure, with the following
  147. *      fields initialized:
  148. *
  149. *   wi_TextFont:    Pointer to an open font.  (I.e. what OpenFont() returns
  150. *                   to you, other than NULL.)
  151. *   wi_BitMap:      Pointer to an initialized, 'working' BitMap structure.
  152. *                   (E.g. Open a window.  Get the pointer to the screen
  153. *                   out of wd_WScreen.  From there the BitMap structure is
  154. *                   at sc_BitMap, which is an offset, not a pointer, into
  155. *                   the Screen structure.)
  156. *   wi_WhichPlane:  Which bitplane you want the routine to draw into.
  157. *                   Numbering begins at zero.  On the Workbench screen
  158. *                   (or any two-bitplane screen) the possible numbers for
  159. *                   wi_WhichPlane are 0 and 1.
  160. *   wi_Left:        Left edge of the 'window' (in character locations)
  161. *                   you want the routine to write into.
  162. *   wi_Top:         Top edge of the 'window' in character locations.
  163. *   wi_Width:       Width of 'window' (also on character locations).
  164. *   wi_Height:      Height of 'window' -- guess what? Character locations.
  165. *
  166. * REGISTER USAGE FOR INITWARPINFO:
  167. *
  168. * d0 - Left, Top, Width, Height, etc.
  169. * d1 - wi_Modulo
  170. * d2 - Scratch
  171. * d3 - Y size of font
  172. * d4 - Scratch
  173. *
  174. * a0 - Pointer to WarpInfo structure with above fields initialized.
  175. * a1 - Addr of top of bitplane, wi_WindowTop, etc.
  176. * a2 - Scratch
  177. * --------------------------------------------------------------------------
  178.  
  179. InitWarpInfo:   movem.l d0-d4/a1-a2,-(sp)
  180.  
  181.                 moveq   #0,d4                   ; Clear scratch.
  182.                 move.w  d4,wi_CurX(a0)          ; Store it in WarpInfo.
  183.  
  184.                 move.w  wi_Width(a0),wi_LastX(a0)  ; Max X position.
  185.  
  186.                 move.l  wi_BitMap(a0),a1        ; Get some stuff from bmap.
  187.  
  188.                 moveq   #0,d2
  189.                 move.w  bm_BytesPerRow(a1),d2   ; #bytes per row in d2
  190.                 move.w  d2,wi_BPMod(a0)         ; #bytes per row->wi_BPMod
  191.  
  192.                 move.w  wi_WhichPlane(a0),d4    ; Get bitplane#.
  193.                 asl.l   #2,d4                   ; Multiply plane# by four.
  194.                 move.l  bm_Planes(a1,d4.l),a1   ; Get address of bitplane.
  195.  
  196.                 moveq   #0,d3
  197.                 move.l  wi_TextFont(a0),a2
  198.                 move.w  tf_YSize(a2),d3         ; Get YSize of font.
  199.  
  200.                 moveq   #0,d1
  201.                 move.l  d2,d1                   ; Copy bytesperrow to d1.
  202.                 mulu.w  d3,d1                   ; YSize*BytesPerRow.
  203.                 move.w  d1,wi_Modulo(a0)        ; Store it in WarpInfo.
  204.  
  205.                 moveq   #0,d4
  206.                 move.l  d1,d4                   ; Copy wi_modulo to scratch.
  207.                 mulu.w  wi_Top(a0),d4           ; Mul by Y offset.
  208.                 add.w   wi_Left(a0),d4          ; Add X offset.
  209.  
  210.                 move.l  a1,a2                   ; BPlane addr to scratch.
  211.                 add.l   d4,a2                   ; Add offset to btpln addr.
  212.                 move.l  a2,wi_WindowTop(a0)     ; Stick in WarpInfo.
  213.                 move.l  a2,wi_CurLine(a0)       ; Stick in WarpInfo.
  214.  
  215.                 moveq   #0,d2
  216.                 move.w  wi_Top(a0),d2           ; Copy Y top to scratch.
  217.                 add.w   wi_Height(a0),d2        ; Add Y height to Y top.
  218.                 move.l  d1,d4                   ; Copy wi_modulo to scratch.
  219.                 mulu.w  d2,d4                   ; Mul by Y offset.
  220.                 add.w   wi_Left(a0),d4          ; Add X offset.
  221.  
  222.                 move.l  a1,a2                   ; BPlane addr to scratch.
  223.                 add.l   d4,a2                   ; Add offset to btpln addr.
  224.                 move.l  a2,wi_LastLine(a0)      ; Stick in WarpInfo.
  225.  
  226.                 movem.l (sp)+,d0-d4/a1-a2
  227.  
  228.                 rts
  229.  
  230. * --------------------------------------------------------------------------
  231. * GOTOXY NEEDS:
  232. *
  233. * d0 - New X position.          \ All regs. but d1 preserved,
  234. * d1 - New Y position.
  235. *
  236. * a0 - Pointer to initialized WarpInfo structure.
  237. *
  238. * NOTE: These positions are given in character locations, like everything
  239. *       else...  The positions are relative to the 'window' you have
  240. *       defined using InitWarpInfo.  Position 0,0 is the character in the
  241. *       top left corner of the window.
  242. *       This routine does no error checking.  (You're supposed to know
  243. *       how big your window is...)
  244. * --------------------------------------------------------------------------
  245.  
  246. GotoXY:         move.w  d0,wi_CurX(a0)      ; Set new X position.
  247.  
  248.                 mulu.w  wi_Modulo(a0),d1    ; Make Y an offset into window
  249.                 add.l   wi_WindowTop(a0),d1 ; Add this offset to the window
  250.                 move.l  d1,wi_CurLine(a0)   ; to make it the new Y position.
  251.  
  252.                 rts
  253.  
  254. * --------------------------------------------------------------------------
  255. * GETXY NEEDS:
  256. *
  257. * a0 - Pointer to an initialized WarpInfo structure.
  258. *
  259. * It returns the current X position in d0 and the current Y
  260. * position in d1.
  261. * --------------------------------------------------------------------------
  262.  
  263. GetXY:          move.l  wi_CurLine(a0),d1   ; Get current Y addr
  264.                 sub.l   wi_WindowTop(a0),d1 ; Sub window to get Y offset.
  265.                 divu.w  wi_Modulo(a0),d1    ; Should not be a remainder.
  266.  
  267.                 moveq   #0,d0
  268.                 move.w  wi_CurX(a0),d0      ; Get current X position.
  269.  
  270.                 rts
  271.  
  272. * --------------------------------------------------------------------------
  273. * WARPTEXT NEEDS:
  274. *
  275. * d0 - Number of characters to type. (count)
  276. *
  277. * a0 - Pointer to an initialized WarpInfo structure.  (See InitWarpInfo)
  278. * a1 - Address of string of characters to type.
  279. *
  280. * REGISTER USAGE FOR WARPTEXT:  (All regs preserved but d0 which will be 0)
  281. *
  282. * d0 - Number of characters to type (count)
  283. * d1 - Character to be emitted
  284. * d2 - LoChar
  285. * d3 - HiChar
  286. * d4 - Current X position
  287. * d5 - Scratch
  288. * d7 - Bitplane modulo: add to get to next raster line in bitplane.
  289. *
  290. * a0 - Pointer to WarpInfo structure
  291. * a1 - Address of string of characters to type
  292. * a2 - Pointer to TextFont structure, address of tf_CharData
  293. * a3 - Addr of Current line.
  294. * a4 - Scratch
  295. * a5 - Scratch
  296. *
  297. * STACK USAGE FOR WARPTEXT:
  298. *
  299. *  0(sp) - Last line
  300. *  4(sp) - Top line
  301. *  8(sp) - tf_YSize
  302. * 12(sp) - tf_Modulo: add it to get to next line in font data
  303. * 16(sp) - wi_Modulo: add it to get to next line in bitplane 'window'
  304. * 20(sp) - Maximum (last) possible X position on a line
  305. * --------------------------------------------------------------------------
  306.  
  307. sp_LastLine:    equ     0   ; Offsets into stack to get at this data.
  308. sp_TopLine:     equ     4
  309. sp_YSize:       equ     8
  310. sp_tf_Mod:      equ     12
  311. sp_wi_Mod:      equ     16
  312. sp_LastX:       equ     20
  313.  
  314. NoChar:         equ     256 ; This is where the empty-box char is. ???
  315.  
  316. WarpText:   movem.l d1-d5/d7/a2-a5,-(sp)
  317.  
  318.             moveq   #0,d4
  319.             move.w  wi_CurX(a0),d4      ; Get current X position.
  320.  
  321.             moveq   #0,d5
  322.             move.w  wi_LastX(a0),d5     ; Get maximum X position.
  323.             move.l  d5,-(sp)            ; Stick it on stack.  (1st item)
  324.  
  325.             move.w  wi_Modulo(a0),d5    ; Get wi_Modulo.
  326.             move.l  d5,-(sp)            ; Stick it on stack.  (2nd item)
  327.  
  328.             move.l  wi_TextFont(a0),a2  ; Use TextFont to get some stuff:
  329.  
  330.               moveq   #0,d2
  331.               move.b  tf_LoChar(a2),d2    ; Get tf_LoChar.
  332.  
  333.               moveq   #0,d3
  334.               move.b  tf_HiChar(a2),d3    ; Get tf_HiChar.
  335.  
  336.               move.w  tf_Modulo(a2),d5    ; Get tf_Modulo.
  337.               move.l  d5,-(sp)            ; Stick it on stack.  (3rd item)
  338.  
  339.               move.w  tf_YSize(a2),d5     ; Get tf_YSize
  340.               move.l  d5,-(sp)            ; Stick it on stack.  (4th item)
  341.  
  342.               move.l  tf_CharData(a2),a2  ; Replace textfont w/ tf_Chardata.
  343.  
  344.             move.l  wi_WindowTop(a0),a4 ; Get addr of wi_WindowTop.
  345.             move.l  a4,-(sp)            ; Stick it on stack.  (5th item)
  346.  
  347.             move.l  wi_LastLine(a0),a4  ; Get addr of wi_LastLine.
  348.             move.l  a4,-(sp)            ; Stick it on stack.  (6th item)
  349.  
  350.             move.l  wi_CurLine(a0),a3   ; Get addr of wi_CurLine.
  351.  
  352.             moveq   #0,d7
  353.             move.w  wi_BPMod(a0),d7     ; Get wi_BPMod.
  354.  
  355.             subq    #1,d0               ; Take one from count.
  356.             moveq   #0,d1               ; Clear d1 because using .b size.
  357.             subq    #1,d4               ; Take one from Current X.
  358.  
  359. DoNextChar:   addq    #1,d4               ; Add 1 to Current X.
  360. DoNextSinAdd: move.b  (a1)+,d1            ; Move char to emit to d1.
  361.               cmpi.b  #32,d1              ; Is it a space?
  362.                beq     Blank
  363.               cmp.b   d2,d1               ; Compare with LoChar.
  364.                blt     BoffoChar           ; May be a LF, FF, CR, etc.
  365.               cmp.b   d3,d1               ; Compare with HiChar.
  366.                blt     DoNoChar
  367.  
  368.               move.l  a2,a4               ; Copy tf_CharData to scratch.
  369.               sub.l   d2,d1               ; Sub LoChar from char.
  370.               adda.l  d1,a4               ; Add char to tf_CharData.
  371.  
  372. DoChar:       move.l  a3,a5               ; Copy current line to scratch.
  373.               adda.l  d4,a5               ; Add XPos to current line.
  374.  
  375.               move.l  sp_YSize(sp),d5     ; YSize is loop count.
  376.               subq.l  #1,d5
  377. MoveChar:       move.b  (a4),(a5)           ; Move line of char to bitplane.
  378.                 adda.l  sp_tf_Mod(sp),a4    ; Add tf_Modulo to tf_Chardata.
  379.                 adda.l  d7,a5               ; Add wi_BPMod to bitplane.
  380.                  dbra    d5,MoveChar
  381.  
  382. Blank:        cmp.l   sp_LastX(sp),d4     ; Compare max X and Current X...
  383.                ble     GotoDoNext          ; Do next if current <= max.
  384.  
  385. DoLF:         moveq   #0,d4               ; Xpos is zero now.
  386.  
  387. DoCR:         cmpa.l  (sp),a3             ; CMP sp_LastLine with current.
  388.                beq     GotoNSA             ; Wrap on line if equ.
  389.  
  390.               adda.l  sp_wi_Mod(sp),a3    ; Point at next line.
  391.                bra     GotoNSA             ; Do another character.
  392.  
  393. DoNoChar:   move.l  a2,a4               ; Copy tf_Chardata to scratch.
  394.             add.l   #NoChar,a4          ; Point at empty-box char.
  395.              bra     DoChar              ; Do the empty-box char.
  396.  
  397. BoffoChar:  cmpi.l  #10,d1              ; Is is a linefeed?
  398.              beq     DoLF
  399.             cmpi.l  #12,d1              ; Is it a formfeed?
  400.              beq     DoFF
  401.             cmpi.l  #13,d1              ; Is it a CR?
  402.              beq     DoCR
  403.              bra     DoNoChar           ; Fine. Put up the box.
  404.  
  405. DoFF:       moveq   #0,d4               ; Make X pos zero.  |  It doesn't
  406.             move.l  sp_TopLine(sp),a3   ; Point at top      |  CLS yet.
  407.              bra     GotoNSA
  408.  
  409. GotoDoNext: dbra    d0,DoNextChar       ; Keep looping?
  410.              bra     WindUp              ; Loop is done. Clean up & bail.
  411.  
  412. GotoNSA:    dbra    d0,DoNextSinAdd     ; Do NextChar without adding.
  413.  
  414. WindUp:     addq.l  #8,sp               ; Get rid of stuff kept on stack.
  415.             addq.l  #8,sp
  416.             addq.l  #8,sp
  417.  
  418.             move.w  d4,wi_CurX(a0)      ; Store current X for next time.
  419.             move.l  a3,wi_CurLine(a0)   ; Store current Y for next time.
  420.  
  421.             movem.l (sp)+,d1-d5/d7/a2-a5
  422.  
  423.             rts
  424.  
  425.         END
  426.  
  427.